package com.aiwiown.snackmq.broker.handler.console;

import com.aiwiown.snackmq.broker.auth.AuthorizationService;
import com.aiwiown.snackmq.cluster.metadata.MetadataManager;
import com.aiwiown.snackmq.common.auth.Action;
import com.aiwiown.snackmq.common.handler.MessageHandler;
import com.aiwiown.snackmq.common.handler.RequestContext;
import com.aiwiown.snackmq.common.message.Message;
import com.aiwiown.snackmq.common.message.MessageStatus;
import com.aiwiown.snackmq.common.message.MessageType;
import lombok.extern.slf4j.Slf4j;

/**
 * 一个抽象基类，用于处理需要元数据 Leader 权限的控制台请求。
 * <p>
 * 它封装了所有控制台管理类 Handler 的通用模板代码，包括：
 * <ul>
 *     <li>权限验证 (要求对 CLUSTER 资源有 MANAGE 权限)</li>
 *     <li>Leader 节点检查</li>
 *     <li>向客户端自动发送重定向响应</li>
 *     <li>统一的异常处理和错误响应封装</li>
 * </ul>
 * 子类只需实现 {@link #doHandle(RequestContext, Message)} 方法来执行其特定的业务逻辑。
 * </p>
 */
@Slf4j
public abstract class AbstractLeaderRequiredConsoleHandler implements MessageHandler {

    protected final MetadataManager metadataManager;
    protected final AuthorizationService authorizationService;

    protected AbstractLeaderRequiredConsoleHandler(MetadataManager metadataManager, AuthorizationService authorizationService) {
        this.metadataManager = metadataManager;
        this.authorizationService = authorizationService;
    }

    @Override
    public final void handle(RequestContext ctx, Message request) {
        try {
            // 1. 统一的权限检查
            authorizationService.authorize(request.getProperty("authToken"), Action.MANAGE, new AuthorizationService.Resource("CLUSTER", "*"));

            // 2. 统一的 Leader 检查与重定向
            if (!metadataManager.isLeader()) {
                String leaderAddress = metadataManager.getLeaderAddress();
                if (leaderAddress != null) {
                    ctx.writeResponse(Message.builder()
                            .type(MessageType.RESPONSE)
                            .messageId(request.getMessageId())
                            .status(MessageStatus.REDIRECT)
                            .property("redirectAddress", leaderAddress)
                            .build());
                    return;
                }
                // 如果没有 Leader，这是一个严重的系统状态问题
                throw new IllegalStateException("No metadata leader available to serve the request.");
            }

            // 3. 委托给子类的具体实现
            doHandle(ctx, request);

        } catch (Exception e) {
            // 4. 统一的异常处理
            log.error("Error processing console request for type {}: {}", getMessageType(), e.getMessage(), e);
            ctx.writeResponse(Message.builder()
                    .type(MessageType.RESPONSE)
                    .messageId(request.getMessageId())
                    .status(MessageStatus.FAILED)
                    .errorMessage("Internal server error: " + e.getMessage())
                    .build());
        }
    }

    /**
     * 子类实现此方法来执行其特定逻辑。
     * <p>
     * 在此方法被调用时，可以假定以下条件已满足：
     * <ul>
     *     <li>用户权限已验证通过。</li>
     *     <li>当前节点是元数据 Leader。</li>
     * </ul>
     *
     * @param ctx     请求上下文
     * @param request 客户端请求
     */
    protected abstract void doHandle(RequestContext ctx, Message request);
}